package com.origin.multimedia.music.service

import android.app.*
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.IBinder
import android.text.TextUtils
import android.util.Log
import android.widget.RemoteViews
import android.widget.Toast
import androidx.annotation.RequiresApi
import tv.danmaku.ijk.media.player.IMediaPlayer
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.origin.multimedia.R
import com.origin.multimedia.music.*
import com.origin.multimedia.music.bean.MusicInfo
import com.origin.multimedia.music.utils.MusicUtils
import com.origin.utils.AnnotationList
import com.origin.utils.ToastUtils
import com.origin.utils.image.GlideApp
import com.origin.utils.log.LogUtils
import com.origin.utils.log.LogVariateUtils
import com.origin.utils.screen.ScreenStatusController
import com.origin.utils.time.TimeUtil
import java.util.*

class MediaService : Service(), IMediaPlayer.OnErrorListener, IMediaPlayer.OnPreparedListener,
    IMediaPlayer.OnBufferingUpdateListener, IMediaPlayer.OnCompletionListener {
    //ijk播放器
    private lateinit var ijkAudioPlayer: IjkAudioPlayer
    private var isPrepared = false
    private var isStop = false
    private var isPause = false

    //是否播放过音乐、防止多次启动时setPathAndPrepare 异常（无法捕获）
    private var isInit = false

    //记录播放uri
    private var oldUri: String? = ""

    private val NOTIFICATION_ID = 0x11

    val notificationManager :NotificationManager by lazy {
        getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    }

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()

        LogUtils._e("crashPath  onCreate")
        initAudioListener()
        ScreenStatusController.addScreenChangeBroadCast(this@MediaService)
        //常驻通知栏
        createMusicNotification(this)
    }

    private fun initAudioListener() {
        ijkAudioPlayer = IjkAudioPlayer()
        ijkAudioPlayer.getPlayer().setOnErrorListener(this)
        ijkAudioPlayer.getPlayer().setOnPreparedListener(this)
        ijkAudioPlayer.getPlayer().setOnBufferingUpdateListener(this)
        ijkAudioPlayer.getPlayer().setOnCompletionListener(this)
    }

    fun getUrl(musicInfo: MusicInfo): String {
        return if (musicInfo.isNetMusic) {
            ProxyCacheManager.getProxy(this).getProxyUrl(musicInfo.musicUrl)
        } else {
            musicInfo.musicUrl
        }
    }


    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        if (intent.action != null) {
            when (intent.action) {
                CONTINUE_PLAY -> if (!TextUtils.isEmpty(oldUri)) {
                    if (isPrepared && isPause) {
                        ijkAudioPlayer.start()
                        isPause = false
                    }
                    MusicControlUtils.setPlayStatus(PlayStatusAnnotation.CONTINUE_PLAY)
                    updateNotificationShow(MusicPlayList.getCurrentPlay())
                }
                PLAY -> {
                    val playPosition = intent.getIntExtra(PLAY_URI, 0)
                    val musicInfo = MusicPlayList.play(playPosition)
                    val uri = musicInfo.musicUrl
                    val sameUri = oldUri == uri
                    oldUri = uri
                    //是否是暂停
                    if (isPrepared && isPause) {

                        if (sameUri) {
                            ijkAudioPlayer.start()
                        } else {
                            ijkAudioPlayer.stop()
                            ijkAudioPlayer.reset()
                            val proxyUri = getUrl(musicInfo)
                            ijkAudioPlayer.setPathAndPrepare(proxyUri)
                        }

                        isPause = false
                        //当停止播放时
                    } else if (isStop || ijkAudioPlayer.getPlayer().isPlaying() || !sameUri) {
                        if (sameUri) {

                        } else {
                            ijkAudioPlayer.stop()
                            ijkAudioPlayer.reset()
                            LogUtils._e("YangKing uri2 $uri ")
                            var proxyUri = getUrl(musicInfo)
                            ijkAudioPlayer.setPathAndPrepare(proxyUri)
                        }

                    } else {
                        if (!isInit) {
                            val proxyUri = getUrl(musicInfo)

                            ijkAudioPlayer.setPathAndPrepare(proxyUri)
                        }
                    }
                    MusicControlUtils.setPlayStatus(PlayStatusAnnotation.PLAY)
                    updateNotificationShow(MusicPlayList.play(playPosition))

                }

                NEXT -> {
                    MediaService.startPlay(this, MusicPlayList.nextPoint())
                    MusicControlUtils.setPlayStatus(PlayStatusAnnotation.NEXT)
                }
                PREVIOUS -> {
                    MediaService.startPlay(this, MusicPlayList.previousPoint())
                    MusicControlUtils.setPlayStatus(PlayStatusAnnotation.PREVIOUS)
                }
                SWITCH -> {
                    if (isPause) {
                        MediaService.continuePlay(this)
                    } else {
                        MediaService.pausePlay(this)
                    }
                }
                SEEKTO -> {
                    if (ijkAudioPlayer.getPlayer().isPlaying()) {
                        val seekToTime = intent.getLongExtra(SEEKTOTIME, 0)
                        val time: Long = seekToTime * ijkAudioPlayer.getPlayer().duration / 100
                        ijkAudioPlayer.seekTo(time)
                    }
                }
                PAUSE -> if (ijkAudioPlayer.getPlayer().isPlaying()) {
                    ijkAudioPlayer.pause()
                    isPause = true
                    MusicControlUtils.setPlayStatus(PlayStatusAnnotation.PAUSE)
                    updateNotificationShow(MusicPlayList.getCurrentPlay())
                }
                STOP -> if (ijkAudioPlayer.getPlayer().isPlaying()) {
                    ijkAudioPlayer.stop()
                    isPrepared = false
                    isStop = true
                    MusicControlUtils.setPlayStatus(PlayStatusAnnotation.STOP)
                }
                STOP_PLAY_SERVICE -> {
                    stopSelf()
                    MusicControlUtils.setPlayStatus(PlayStatusAnnotation.STOP_PLAY_SERVICE)
                }
            }
        }
        return START_NOT_STICKY
    }

    /**
     * 更新通知栏样式
     */
    private fun updateNotificationShow(musicInfo: MusicInfo) {

        remoteViewsSmall?.apply {
            this.setTextViewText(R.id.tv_notification_song_name, musicInfo.songName)
            this.setTextViewText(R.id.tv_notification_singer, musicInfo.artist)
        }
        remoteViewsBig?.apply {
            this.setTextViewText(R.id.tv_notification_song_name, musicInfo.songName)
            this.setTextViewText(R.id.tv_notification_singer, musicInfo.artist)


        }


        if (isPause) {
            R.drawable.ic_play
        } else {
            R.drawable.ic_pause
        }.let {
            remoteViewsBig?.apply {
                this.setImageViewResource(R.id.play, it)
            }
            remoteViewsSmall?.apply {
                this.setImageViewResource(R.id.play, it)
            }
        }

        GlideApp.with(this@MediaService).asBitmap().load(musicInfo.albumCover).override(300, 300)
            .into(object : CustomTarget<Bitmap>() {
                override fun onResourceReady(
                    resource: Bitmap,
                    transition: Transition<in Bitmap>?
                ) {
                    ScreenStatusController.setActionBitmap(resource)
                    remoteViewsBig?.apply {
                        this.setImageViewBitmap(R.id.albumCoverIv, resource)
                    }
                    remoteViewsSmall?.apply {
                        this.setImageViewBitmap(R.id.albumCoverIv, resource)
                    }
                    notificationManager.notify(NOTIFICATION_ID, notification)
                }

                override fun onLoadCleared(placeholder: Drawable?) {
                }
            })


    }

    @RequiresApi(Build.VERSION_CODES.N)
    override fun onDestroy() {
        super.onDestroy()
        ScreenStatusController.removeScreenChangeBroadCast(this@MediaService)
        ijkAudioPlayer.stop()
        ijkAudioPlayer.release()
        isPrepared = false
        clearPlayProgressListener()
    }

    override fun onError(iMediaPlayer: IMediaPlayer, i: Int, i1: Int): Boolean {
        isPrepared = false
        isStop = true
        Toast.makeText(this, "出错了、请重试！", Toast.LENGTH_SHORT).show()
        return false
    }

    override fun onBufferingUpdate(p0: IMediaPlayer?, p1: Int) {
        if (p1 != 0)
            MusicControlUtils.bufferingProgress(p1)
    }


    var timer: Timer? = null;
    private fun startPlayProgressListener() {
        timer = TimeUtil.timer(1000, object : TimeUtil.TimerImp {
            override fun run() {
                val position = ijkAudioPlayer.getPlayer().currentPosition
                val duration = ijkAudioPlayer.getPlayer().duration
                val progress = position * 100 / (if (duration == 0L) 1 else duration)
                MusicControlUtils.playProgress(
                    progress.toInt(),
                    TimeUtil.secondToTime(position / 1000)
                )

            }
        })
    }

    override fun onCompletion(p0: IMediaPlayer) {
        MusicControlUtils.playProgress(
            100,
            TimeUtil.secondToTime(ijkAudioPlayer.getPlayer().duration / 1000)
        )
    }


    private fun clearPlayProgressListener() {
        timer?.cancel()
        timer = null;
    }

    override fun onPrepared(iMediaPlayer: IMediaPlayer) {
        isInit = true
        isPrepared = true
        isStop = false
        iMediaPlayer.start()
        isPause = false
        startPlayProgressListener()
    }

    var remoteViewsBig: RemoteViews? = null
    var remoteViewsSmall: RemoteViews? = null
    var notification: Notification? = null

    private fun createMusicNotification(context: Context) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                "subscribe", "MediaService",
                NotificationManager.IMPORTANCE_LOW  // 不要有提示音
            )
            channel.canBypassDnd();//可否绕过，请勿打扰模式
            channel.lockscreenVisibility = Notification.VISIBILITY_SECRET;//锁屏显示通知
            channel.setSound(null, null);
            channel.setBypassDnd(true);//设置可以绕过，请勿打扰模式
            notificationManager.createNotificationChannel(channel)
        }
        remoteViewsBig = RemoteViews(context.packageName, R.layout.notify_custom)
        remoteViewsSmall = RemoteViews(context.packageName, R.layout.notification_small)
        if (isPause) {
            R.drawable.ic_play
        } else {
            R.drawable.ic_pause
        }.let {
            remoteViewsBig?.apply {
                this.setImageViewResource(R.id.play, it)
            }
            remoteViewsSmall?.apply {
                this.setImageViewResource(R.id.play, it)
            }
        }

        addOnClick()

        val intent = Intent.makeRestartActivityTask(ComponentName(context, "com.origin.museum.music.activity.MusicPlayActivity"));
        val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)

        notification = NotificationCompat.Builder(this, "subscribe")
            .setOngoing(true)
            .setContentIntent(pendingIntent)
            .setSmallIcon(R.drawable.ic_pause)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_pause))
            .setAutoCancel(false)
            .setCustomBigContentView(remoteViewsBig)
            .setContent(remoteViewsSmall)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .build()

        startForeground(NOTIFICATION_ID, notification)
    }

    private fun addOnClick() {
        nextOnClick()
        previousOnClick()
        playOnClick()
        closeOnClick()
    }

    private fun closeOnClick() {
        val closeIntent = Intent(this@MediaService, MediaService::class.java)
        closeIntent.action = STOP_PLAY_SERVICE
        val closePend = PendingIntent.getService(this@MediaService, RELEASE, closeIntent, 0)
        createPendingIntent(R.id.close, closePend)
    }

    private fun playOnClick() {
        val switchIntent = Intent(this@MediaService, MediaService::class.java)
        switchIntent.action = SWITCH
        val switchPend = PendingIntent.getService(this@MediaService, RELEASE, switchIntent, 0)
        createPendingIntent(R.id.play, switchPend)
    }

    private fun previousOnClick() {
        val previousIntent = Intent(this@MediaService, MediaService::class.java)
        previousIntent.action = PREVIOUS
        val previousPend = PendingIntent.getService(this@MediaService, RELEASE, previousIntent, 0)
        createPendingIntent(R.id.previous_song, previousPend)
    }

    private fun nextOnClick() {
        val nextIntent = Intent(this@MediaService, MediaService::class.java)
        nextIntent.action = NEXT
        val nextPend = PendingIntent.getService(this@MediaService, RELEASE, nextIntent, 0)
        createPendingIntent(R.id.next_song, nextPend)
    }

    private fun createPendingIntent(viewId: Int, pendingIntent: PendingIntent) {
        remoteViewsBig?.apply {
            setOnClickPendingIntent(viewId, pendingIntent)
        }
        remoteViewsSmall?.apply {
            setOnClickPendingIntent(viewId, pendingIntent)
        }
    }


    companion object {
        private const val PLAY_URI = "play_uri"
        private const val PLAY = "play"
        private const val CONTINUE_PLAY = "continue_play"
        private const val PAUSE = "pause"
        private const val STOP = "stop"
        private const val SEEKTO = "SEEKTO"
        private const val SEEKTOTIME = "seekToTime"
        private const val NEXT = "next"
        private const val PREVIOUS = "previous"
        private const val SWITCH = "switch"
        const val STOP_PLAY_SERVICE = "stop_play_service"
        const val RELEASE = 101
        fun startPlay(context: Context, position: Int) {
            context.startService(
                Intent(context, MediaService::class.java).putExtra(
                    PLAY_URI,
                    position
                ).setAction(PLAY)
            )
        }

        fun nextPlay(context: Context) {
            context.startService(Intent(context, MediaService::class.java).setAction(NEXT))
        }

        fun previousPlay(context: Context) {
            context.startService(Intent(context, MediaService::class.java).setAction(PREVIOUS))
        }

        //继续播放、若已发生暂停
        fun continuePlay(context: Context) {
            context.startService(Intent(context, MediaService::class.java).setAction(CONTINUE_PLAY))
        }

        fun pausePlay(context: Context) {
            context.startService(Intent(context, MediaService::class.java).setAction(PAUSE))
        }

        fun stopPlay(context: Context) {
            context.startService(Intent(context, MediaService::class.java).setAction(STOP))
        }

        fun seekTo(context: Context, time: Long) {
            context.startService(
                Intent(context, MediaService::class.java).putExtra(
                    SEEKTOTIME,
                    time
                ).setAction(SEEKTO)
            )
        }

    }


}